iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
自我挑戰組

Rayeee 的 TypeScript 的學習日記系列 第 10

<20230911> 再...再吸口... 再吸一口 Enum

  • 分享至 

  • xImage
  •  

昨天有提到在查詢 Enum 時,看了官方文件以及其他文章後,發現對 Enum 少了滿多基本的認識,之前使用都是覺得很方便而已ㄝ並不知道一些底層運作或是 edge case 會怎麼跑

而既然鐵人賽的標題是叫做學習日記,那就趁這次來把多學到的知識整理下來吧


先來講講昨天節錄官方文件的最後一句話

TypeScript provides both numeric and string-based enums.

TypeScript 有提供 數字枚舉 以及 字串枚舉

什麼是數字枚舉呢?

數字枚舉

  • 在使用 Enum 時,如不賦值,會默認使用 數字枚舉
  • 自動遞增值特性,如不賦值,第一個參數預設會是 0,之後已連續整數遞增。
  • 如果 Enum 賦值數字,那後面的值也會由該值為起點遞增

如以下範例:

enum Direction {
    Up,
    Down,
    Left,
    Right
}

因為沒有賦值,TypeScript 會自動把第一個枚舉值預設為 0,之後就遞增 +1 +1

enum Direction {
    Up,     // 0
    Down,   // 1
    Left,   // 2
    Righ   // 3
}

等價於下面寫法

enum Direction {
    Up = 0,
    Down = 1,
    Left = 2,
    Right = 3
}

編譯成 JavaScript,可以看到兩邊的值相同

https://ithelp.ithome.com.tw/upload/images/20230911/20162544AigbbZ4tvG.png

自動遞增的這種行為, 他的好處是可以讓我們更專注在同組 Enum 中每個值是不同的這一件事,而不用花費心力去設定預設值

另外,如果數字枚舉的數字是從中間開始,那後面的值也會由該值為起點遞增
直接看範例

enum Direction {
    East, 
    West, 
    South, 
    North,
    Northeast = 0,
    Northwest,
    Southeast,
    Southwest,
}

這樣寫的話,從 East 開始就沒有賦予初始值,依照前面所說的自動預設值, East 會預設為 0,但 Northeast 我們有賦予值 0,所以 TypeScript 會從 Northeast 再重新遞增

enum Direction {
    East,           // 0
    West,           // 1
    South,          // 2
    North,          // 3
    Northeast = 0,  // 0 <== 重新開始遞增
    Northwest,      // 1
    Southeast,      // 2
    Southwest,      // 3
}

不過這樣寫就會出現一些問題,像是這樣判斷的時候就會看起來怪怪的

console.log(Direction.East === Direction.Northeast); // true

語意上看起來怪怪的,反而失去了我們使用 Enum 的初衷,增加可讀性

字串枚舉

字串枚舉中沒有自動遞增的行為,且一定要手動預設值
好處是可以更進一步的增加可閱讀性

enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

可以注意的是 數字枚舉 以及 字串枚舉 編譯成 JavaScript 時的表現不太相同

https://ithelp.ithome.com.tw/upload/images/20230911/20162544yWwF4wwvag.png

字串枚舉 + 數字枚舉 = 異構枚舉

Heterogeneous enums
就是兩個摻在一起,有字串枚舉也有數字枚舉,技術上是做的得到,但是目前本身也沒有碰過使用到的情境,一般選一種使用就很夠了

官方文件 heterogeneous-enums 也有提到

Unless you’re really trying to take advantage of JavaScript’s runtime behavior in a clever way, it’s advised that you don’t do this.

除非你真的想用 巧妙的方式 利用 JavaScript 運行的行為而使用異構枚舉,不然不建議這樣做(是奪巧妙

enum Heterogeneous {
    Success = "SUCCESS",
    Fail = 0
}

常數枚舉/ const 枚舉

常數枚舉在編譯時會被簡化成 JavaScript 中的普通物件,不會生成額外的程式碼

間單來說這樣使用編譯出來的 JavaScript 就不會有這個枚舉類型了

const enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

https://ithelp.ithome.com.tw/upload/images/20230911/20162544FfbF17ahOv.png

但是在執行上,跟前面的範例使用起來都差不多

https://ithelp.ithome.com.tw/upload/images/20230911/20162544WxZGAzAxm8.png

還是會正常的運作

主要的優點是可以簡化編譯後的輸出,因為編譯後 const Enum 不會在 JavaScript 中出現,所以可以提升專案效能、減輕專案重量

參考資料

無敵官網 Enums
其他人的鐵人賽 枚舉 / 列舉 (Enum) by 威爾豬


上一篇
<20230910> Day9. Enum 枚舉
下一篇
<20230912> Day11. 初探探 Interfaces
系列文
Rayeee 的 TypeScript 的學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言